package team.se.tms.util;

import org.springframework.web.multipart.MultipartFile;
import team.se.tms.constant.FormatConstant;
import team.se.tms.constant.PathConstant;
import team.se.tms.dto.AssignmentFile;
import team.se.tms.dto.AssignmentRelevantDataDetail;
import team.se.tms.dto.CourseMaterialFile;
import team.se.tms.enums.ResultEnum;
import team.se.tms.exception.FileDestroyException;
import team.se.tms.exception.FileStoreException;
import team.se.tms.po.AssignmentInfo;

import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件处理工具类
 *
 * @author winkyle
 * @date 2018/11/8
 */
public class FileUtil {

    /**
     * 获得文件大小
     *
     * @param file 文件
     * @return 文件大小
     * @create on 2018/11/30 by winkyle
     */
    public static String getFileSize(File file) {
        long unit = 1024;
        long size = file.length();
        DecimalFormat df = new DecimalFormat("#.00");
        if(size<=0){
            return "0B";
        }
        if (size < unit){
            return df.format((double) size) + "B";
        }
        if (size < unit*unit){
            return df.format((double) size / unit) + "KB";
        }
        if (size < unit*unit*unit){
            return df.format((double) size / (unit*unit)) + "MB";
        }
        return df.format((double) size / (unit*unit*unit)) + "GB";
    }

    /**
     * 获得不带扩展名的文件名
     *
     * @param fileName 文件名
     * @return 不带扩展名的文件名
     * @create on 2018/11/30 by winkyle
     */
    public static String GetFileNameWithoutExtension(String fileName) {
        return fileName.substring(0,fileName.lastIndexOf("."));
    }

    /**
     * 获得文件扩展名
     *
     * @param fileName 文件名
     * @return 文件扩展名
     * @create on 2018/11/30 by winkyle
     */
    public static String getExtension(String fileName) {
        return fileName.substring(fileName.lastIndexOf("."),fileName.length());
    }

    /**
     * 删除指定文件
     *
     * @param filePath 删除的文件路径与名
     * @create on 2018/11/27 by winkyle
     */
    private static void destroy(String filePath){
        try {
            File file = new File(filePath);
            file.delete();
        } catch (Exception e) {
            throw new FileDestroyException(ResultEnum.Error);
        }
    }

    /**
     * 删除文件
     *
     * @param path 删除的文件的基路径下的相对路径路径与名
     * @create on 2018/11/27 by winkyle
     */
    public static void destroyFile(String path) {
        destroy(PathConstant.FILE_STORE_BASE + path);
    }

    /**
     * 创建目录
     *
     * @param path 目录路径
     * @return 创建创建结果
     * @create on 2018/11/27 by winkyle
     */
    private static Boolean createDirectory(String path) {
        File file = new File(path);
        if(!file.exists()) {
            return file.mkdirs();
        }
        return true;
    }

    /**
     * 将文件写入指定路径
     *
     * @param path 存储路径
     * @param multipartFile 文件
     * @return 存储结果
     * @throws Exception 异常
     * @create on 2018/11/27 by winkyle
     */
    private static void store(String path, MultipartFile multipartFile){
        try {
            BufferedOutputStream out;
            out = new BufferedOutputStream(new FileOutputStream(new File(path)));
            out.write(multipartFile.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            throw new FileStoreException(ResultEnum.WRITE_WRONG);
        }
    }

    /**
     * 存储文件，并返回文件是否存储成功
     *
     * @param path 存储路径
     * @param fileName 文件名
     * @param multipartFile 文件
     * @param typeFormat 文件类型格式
     * @return 文件是否存储成功
     * @create on 2018/11/27 by winkyle
     */
    public static Boolean storeFile(String path, String fileName, MultipartFile multipartFile, String typeFormat){
        if(typeFormat!=null&&!StringUtil.hasMatch(multipartFile.getContentType(),typeFormat)){
            throw new FileStoreException(ResultEnum.FILE_TYPE_WRONG);
        }
        String basePath = PathConstant.FILE_STORE_BASE + path;
        if(!createDirectory(basePath)){
            throw new FileStoreException(ResultEnum.DIRECTORY_NO_EXIST);
        }
        store(basePath + fileName,multipartFile);
        return true;
    }

    /**
     * 存储文件，并返回文件是否存储成功
     *
     * @param path 存储路径
     * @param fileName 文件名
     * @param multipartFile 文件
     * @return 文件是否存储成功
     * @create on 2018/11/27 by winkyle
     */
    public static Boolean storeFile(String path, String fileName, MultipartFile multipartFile){
        return storeFile(path, fileName, multipartFile, null);
    }

    /**
     * 解析课程资料，获取类型，大小
     *
     * @param courseMaterialFile 课程资料
     * @return 解析后的课程资料
     * @create on 2018/11/30 by winkyle
     */
    public static CourseMaterialFile analysisCourseMaterialFile(CourseMaterialFile courseMaterialFile){
        if(courseMaterialFile==null) {
            return null;
        }
        File file = new File(PathConstant.FILE_STORE_BASE+courseMaterialFile.getCourseMaterialAddress());
        if(!file.exists()) {
            return null;
        }
        courseMaterialFile.setFileType(getExtension(file.getName()));
        courseMaterialFile.setFileSize(getFileSize(file));
        return courseMaterialFile;
    }

    /**
     * 解析课程资料列表，获取类型，大小
     *
     * @param courseMaterialFiles 课程资料列表
     * @return 解析后的课程资料列表
     * @create on 2018/11/30 by winkyle
     */
    public static List<CourseMaterialFile> analysisCourseMaterialFiles(List<CourseMaterialFile> courseMaterialFiles){
        List<CourseMaterialFile> files = new ArrayList<>();
        for (CourseMaterialFile courseMaterialFile:courseMaterialFiles) {
            files.add(analysisCourseMaterialFile(courseMaterialFile));
        }
        return files;
    }

    /**
     * 解析作业详细数据，获取类型，大小
     *
     * @param assignmentRelevantDataDetail 作业详细数据
     * @return 解析后的作业详细数据
     * @create on 2019/1/1 by winkyle
     */
    public static AssignmentRelevantDataDetail analysisAssignmentRelevantDataDetail(AssignmentRelevantDataDetail assignmentRelevantDataDetail){
        if(assignmentRelevantDataDetail==null) {
            return null;
        }
        File file = new File(PathConstant.FILE_STORE_BASE+assignmentRelevantDataDetail.getAssignmentAddress());
        if(!file.exists()) {
            return null;
        }
        assignmentRelevantDataDetail.setAssignmentSize(getFileSize(file));
        assignmentRelevantDataDetail.setAssignmentType(getExtension(file.getName()));
        return assignmentRelevantDataDetail;
    }

    /**
     * 解析作业详细数据列表，获取类型，大小
     *
     * @param assignmentRelevantDataDetails 作业详细数据列表
     * @return 解析后的作业详细数据列表
     * @create on 2019/1/1 by winkyle
     */
    public static List<AssignmentRelevantDataDetail> analysisAssignmentRelevantDataDetails(List<AssignmentRelevantDataDetail> assignmentRelevantDataDetails){
        List<AssignmentRelevantDataDetail> files = new ArrayList<>();
        for (AssignmentRelevantDataDetail assignmentRelevantDataDetail:assignmentRelevantDataDetails) {
            AssignmentRelevantDataDetail assignmentRelevantDataDetail1 = analysisAssignmentRelevantDataDetail(assignmentRelevantDataDetail);
            if(assignmentRelevantDataDetail1!=null) {
                files.add(assignmentRelevantDataDetail1);
            }
        }
        return files;
    }

    /**
     * 解析作业，获取类型，大小
     *
     * @param assignmentFile 作业
     * @return 解析后的作业
     * @create on 2018/12/31 by winkyle
     */
    public static AssignmentFile analysisAssignmentFile(AssignmentFile assignmentFile){
        if(assignmentFile==null) {
            return null;
        }
        File file = new File(PathConstant.FILE_STORE_BASE+assignmentFile.getAssignmentAddress());
        if(!file.exists()) {
            return null;
        }
        assignmentFile.setFileType(getExtension(file.getName()));
        assignmentFile.setFileSize(getFileSize(file));
        return assignmentFile;
    }
    /**
     * 解析项目作业列表
     *
     * @param assignmentInfoList 项目作业信息
     * @return List<AssignmentFile> 解析后的作业文件信息
     * @create on 2018/12/16 by johnny
     */
    public static List<AssignmentFile> analysisAssignmentFiles(List<AssignmentInfo> assignmentInfoList){
        List<AssignmentFile> assignmentFileList = new ArrayList<>();
        for(AssignmentInfo assignmentInfo:assignmentInfoList){
            AssignmentFile assignmentFile = new AssignmentFile();
            File file = new File(PathConstant.FILE_STORE_BASE+assignmentInfo.getAssignmentAddress());
            if(!file.exists()) {
                continue;
            }
            //System.out.println("2@@@@@@@@@@@@@");
            assignmentFile.setAssignmentId(assignmentInfo.getAssignmentId());
            assignmentFile.setFileType(getExtension(file.getName()));
            assignmentFile.setFileSize(getFileSize(file));
            assignmentFile.setAssignmentName(assignmentInfo.getAssignmentName());
            assignmentFile.setAssignmentVersion(assignmentInfo.getAssignmentVersion());
            assignmentFile.setAssignmentCreateTime(assignmentInfo.getAssignmentCreateTime());
            assignmentFile.setAssignmentUpdateTime(assignmentFile.getAssignmentUpdateTime());
            assignmentFile.setAssignmentAddress(assignmentInfo.getAssignmentAddress());
            assignmentFile.setAssignmentState(assignmentInfo.getAssignmentState());
            assignmentFile.setAssignmentId(assignmentInfo.getAssignmentId());
            assignmentFile.setAssignmentJudgeAddress(assignmentInfo.getAssignmentJudgeAddress());

            assignmentFileList.add(assignmentFile);
            //System.out.println("@@@@@@@@@"+assignmentFile);
        }
        //System.out.println("@@@@@@@@@"+assignmentFileList);
        return assignmentFileList;

    }



    /**
     * 存储图片，并返回图片是否存储成功
     * todo 例子，要被删除的  ,用于限定格式
     * @param path 存储路径
     * @param fileName 文件名
     * @param multipartFile 文件
     * @return 图片是否存储成功
     * @create on 2018/11/27 by winkyle
     */
    public static Boolean storeImage(String path, String fileName, MultipartFile multipartFile){
        return storeFile(path, fileName, multipartFile, FormatConstant.IMAGE_TYPE);
    }
}
